package identical_scheduling_algorithm;

import java.util.ArrayList;
/**
 * 
 * Stellt Methoden bereit die das Streichen für den Algorithmus 1 aus dem Paper ...benötigt.
 * 
 * CrossOfValues() streicht einmal die Anzahl der Maschinen und speichert die noch verbleibenden
 * unter newNumberOfMachines ab. Ebenso steht in  newRoundedJob die noch verbleibende Anzahl von Jobs.
 * getOccupancy() gibt die Belegung der gestrichenen Maschinen zurück.
 * 
 * @author Oliver Hense
 * @author Tim Dopke
 *
 */
public class CrossOff {
	
	private int amountOfDifferentJobs;
	private double maxGap;
	private Cofiguration conf;
	private int  numberOfMachine;
	private int newNumberOfMachines;
	private double [] roundedJobs;
	private double [] newRoundedJobs;
	private int crossOfJobs;
	private  double delta;
	
	

	public CrossOff(double maxGap, Cofiguration conf, int numberOfMachine, double [] roundedJobs,double delta) {
		this.maxGap = maxGap;
		this.conf = conf;
		this.numberOfMachine = numberOfMachine;
		this.roundedJobs = roundedJobs;
		this.newRoundedJobs = new double [roundedJobs.length];
		this.amountOfDifferentJobs = roundedJobs.length;
		this.delta = delta;
	}

	
	public void crossOffValues(){
		
		//Cross off machines
		int m = 0;
		for(int i =0; i< conf.getSolution().size(); i++){
			if(maxGap < conf.getSolution().get(i))
			m = m + (int)Math.ceil(conf.getSolution().get(i) - maxGap);
		}
		newNumberOfMachines = numberOfMachine - m;
		setCrossOfJobs(m);
		
		
		
		//Cross off Jobs of each size 
		int n [] = new int [amountOfDifferentJobs];
		for(int i = 0; i< amountOfDifferentJobs; i++){
			for(int j = 0; j < conf.getSolution().size(); j++){
				if(maxGap < conf.getSolution().get(j))
				n[i] = n[i]+ ((int)Math.ceil(conf.getSolution().get(j) - maxGap) * conf.getMatrix().get(j).get(i));
			}
			
			newRoundedJobs[i] = roundedJobs[i] - n[i];
		}	
		
	
	}
		//Returns the occupancy of the bins
	public ArrayList<Double> getOccupancy(){
		ArrayList<Double> occupancy = new ArrayList<Double>();
		double d = 0.0;
		int factor=0;
		for(int i =0; i< conf.getSolution().size(); i++){
			if(maxGap < conf.getSolution().get(i)){
			factor =  (int)Math.ceil(conf.getSolution().get(i) - maxGap);
			for(int j = 0; j< amountOfDifferentJobs; j++){
				d = d +  (conf.getMatrix().get(i).get(j) * (delta* Math.pow((delta + 1), j)));
			}
				
			for(int j= 0; j< factor; j++)
				occupancy.add(d);
			d = 0.;
			}
		}
		
		return occupancy;
	}
		//getter for rounded jobs
	public double[] getNewRoundedJobs() {
		return newRoundedJobs;
	}
		//getter for number of machines
	public int getNewNumberOfMachines() {
		return newNumberOfMachines;
	}

		// setter for amount of different Jobs
	public void setAmountOfDifferentJobs(int amountOfDifferentJobs) {
		this.amountOfDifferentJobs = amountOfDifferentJobs;
	}


		// setter for MaxGap
	public void setMaxGap(double maxGap) {
		this.maxGap = maxGap;
	}


		//setter for Configuration
	public void setConf(Cofiguration conf) {
		this.conf = conf;
	}

		//setter number of machines
	public void setNumberOfMachine(int numberOfMachine) {
		this.numberOfMachine = numberOfMachine;
	}

		// getter crossed  jobs
	public int getCrossOfJobs() {
		return crossOfJobs;
	}

		// setter crossed jobs
	public void setCrossOfJobs(int crossOfJobs) {
		this.crossOfJobs = crossOfJobs;
	}

}
